package com.cloud.note.service.impl;

import com.cloud.note.dto.attachment.AttachmentResponse;
import com.cloud.note.model.Attachment;
import com.cloud.note.model.Note;
import com.cloud.note.model.User;
import com.cloud.note.model.constant.AttachmentType;
import com.cloud.note.repository.AttachmentRepository;
import com.cloud.note.repository.NoteRepository;
import com.cloud.note.repository.UserRepository;
import com.cloud.note.service.AttachmentService;
import com.cloud.note.service.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class AttachmentServiceImpl implements AttachmentService {

    @Autowired
    private AttachmentRepository attachmentRepository;

    @Autowired
    private NoteRepository noteRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private FileStorageService fileStorageService;

    @Override
    @Transactional
    public AttachmentResponse uploadAttachment(String userId, String noteId, MultipartFile file, String type)
            throws IOException {
        // 检查笔记是否存在
        Note note = noteRepository.findByIdAndUserId(noteId, userId)
                .orElseThrow(() -> new RuntimeException("笔记不存在"));

        // 检查附件类型是否有效
        try {
            AttachmentType.valueOf(type.toUpperCase());
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("无效的附件类型: " + type);
        }

        // 检查用户存储空间是否足够
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        if (user.getStorageUsed() + file.getSize() > user.getStorageLimit()) {
            throw new RuntimeException("存储空间不足");
        }

        // 保存文件
        String filePath = fileStorageService.storeFile(file, userId, noteId);

        // 创建附件记录
        Attachment attachment = new Attachment();
        attachment.setId(UUID.randomUUID().toString());
        attachment.setNoteId(noteId);
        attachment.setName(file.getOriginalFilename());
        attachment.setType(type.toUpperCase());
        attachment.setUri(filePath);
        attachment.setSize(file.getSize());
        attachment.setSynced(false);
        attachment.setCreatedAt(LocalDateTime.now());

        attachmentRepository.save(attachment);

        // 更新用户已使用的存储空间
        user.setStorageUsed(user.getStorageUsed() + file.getSize());
        userRepository.save(user);

        // 标记笔记为未同步
        note.setSynced(false);
        note.setUpdatedAt(LocalDateTime.now());
        noteRepository.save(note);

        return AttachmentResponse.builder()
                .id(attachment.getId())
                .name(attachment.getName())
                .type(attachment.getType())
                .uri(attachment.getUri())
                .size(attachment.getSize())
                .isSynced(attachment.isSynced())
                .createdAt(attachment.getCreatedAt())
                .build();
    }

    @Override
    public List<AttachmentResponse> getNoteAttachments(String userId, String noteId) {
        // 检查笔记是否存在
        noteRepository.findByIdAndUserId(noteId, userId)
                .orElseThrow(() -> new RuntimeException("笔记不存在"));

        List<Attachment> attachments = attachmentRepository.findByNoteIdAndUserId(noteId, userId);

        return attachments.stream()
                .map(attachment -> AttachmentResponse.builder()
                        .id(attachment.getId())
                        .name(attachment.getName())
                        .type(attachment.getType())
                        .uri(attachment.getUri())
                        .size(attachment.getSize())
                        .isSynced(attachment.isSynced())
                        .createdAt(attachment.getCreatedAt())
                        .build())
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void deleteAttachment(String userId, String attachmentId) throws IOException {
        // 查找附件
        Attachment attachment = attachmentRepository.findByIdAndUserId(attachmentId, userId)
                .orElseThrow(() -> new RuntimeException("附件不存在"));

        // 删除文件
        fileStorageService.deleteFile(attachment.getUri());

        // 更新用户存储空间
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        user.setStorageUsed(Math.max(0, user.getStorageUsed() - attachment.getSize()));
        userRepository.save(user);

        // 删除附件记录
        attachmentRepository.delete(attachment);

        // 标记笔记为未同步
        Note note = noteRepository.findById(attachment.getNoteId())
                .orElse(null);

        if (note != null) {
            note.setSynced(false);
            note.setUpdatedAt(LocalDateTime.now());
            noteRepository.save(note);
        }
    }
}